package com.ruoyi.framework.web.service;

import com.ruoyi.common.enums.UserResourceEnum;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.validate.ValidatorUtil;
import com.ruoyi.system.domain.SysUserRole;
import org.springframework.beans.factory.annotation.Autowired;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.RegisterReq;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.user.CaptchaException;
import com.ruoyi.common.exception.user.CaptchaExpireException;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysUserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Objects;

/**
 * 注册校验方法
 *
 * @author ruoyi
 */
@Service
public class SysRegisterService {
    @Autowired
    private ISysUserService userService;
    @Autowired
    private ISysConfigService configService;
    @Autowired
    private RedisCache redisCache;

    /**
     * 注册
     */
    @Transactional(rollbackFor = Exception.class)
    public void register(RegisterReq registerReq) {
        ValidatorUtil.validateEntity(registerReq);

        if (!configService.canRegister()) {
            throw new ServiceException("当前系统没有开启注册功能");
        }

        String username = registerReq.getUsername();
        // 验证码开关
        boolean captchaEnabled = configService.selectCaptchaEnabled();
        if (captchaEnabled) {
            validateCaptcha(registerReq.getCode(), registerReq.getUuid());
        }

        SysUser sysUser = SysUser.create();
        sysUser.setUserName(username);
        // 用户名不能在数据库存在
        if (!userService.checkUserNameUnique(sysUser)) {
            throw new ServiceException("保存用户'" + username + "'失败，注册账号已存在");
        }

        sysUser.setNickName(username);
        sysUser.setPassword(SecurityUtils.encryptPassword(registerReq.getPassword()));

        boolean regFlag = userService.registerUser(sysUser);
        if (!regFlag) {
            throw new ServiceException("注册失败,请联系系统管理人员");
        }

        UserResourceEnum userResourceEnum = UserResourceEnum.getByCode(registerReq.getResource());
        switch (Objects.requireNonNull(userResourceEnum)) {
            case USER_APPOINTMENT_SYSTEM:
                // 设置用户预约系统角色
                SysUserRole.create()
                        .setUserId(sysUser.getUserId())
                        .setRoleId(103L)
                        .save();

                break;

            case BACK_MANAGEMENT_SYSTEM:
                // 设置后台管理系统查询角色
                SysUserRole.create()
                        .setUserId(sysUser.getUserId())
                        .setRoleId(2L)
                        .save();
                break;

            default:
                throw new ServiceException("注册失败,请联系系统管理人员");
        }

        // 记录登录信息
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(
                username, Constants.REGISTER, MessageUtils.message("user.register.success")));
    }

    /**
     * 校验验证码
     *
     * @param code     验证码
     * @param uuid     唯一标识
     * @return 结果
     */
    public void validateCaptcha(String code, String uuid) {
        String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
        String captcha = redisCache.getCacheObject(verifyKey);
        redisCache.deleteObject(verifyKey);
        if (captcha == null) {
            throw new CaptchaExpireException();
        }
        if (!code.equalsIgnoreCase(captcha)) {
            throw new CaptchaException();
        }
    }
}
